package itypes

import (
	"server/share/config"

	"github.com/hwcer/logger"
	"github.com/hwcer/updater"
	"github.com/hwcer/updater/operator"
	"github.com/hwcer/yyds"
)

var ItemsGroup = &itemsRandom{IType: IType{id: config.ITypeItemGroup}}
var ItemsPacks = &itemsRandom{IType: IType{id: config.ITypeItemPacks}}

func init() {
	ItemsGroup.Random = itemsGroupRandom
	ItemsPacks.Random = itemsPacksRandom
}

type itemsRandom struct {
	IType
	Random func(u *updater.Updater, iid, num int32) map[int32]int32
}

// Listener 独立概率
func (this *itemsRandom) Listener(u *updater.Updater, op *operator.Operator) {
	if this.Random == nil {
		logger.Alert("请配置物品组相关处理方法")
		return
	}
	if op.Type != operator.TypesAdd || op.Value <= 0 {
		return
	}
	op.Type = operator.TypesResolve
	r := this.Parse(u, op.IID, int32(op.Value))
	for k, v := range r {
		u.Add(k, v)
	}
}

func (this *itemsRandom) Parse(u *updater.Updater, iid, num int32) map[int32]int32 {
	r := map[int32]int32{}
	this.switchParser(u, iid, num, r, 0)
	return r
}

// parse 解析概率表 物品组或者包
func (this *itemsRandom) doRandom(u *updater.Updater, k, v int32, r map[int32]int32, n int32) {
	if this.Random == nil {
		logger.Alert("itemsRandom Random handle is nil")
		return
	}
	rs := this.Random(u, k, v)
	for i, j := range rs {
		this.switchParser(u, i, j, r, n)
	}
}

func (this *itemsRandom) switchParser(u *updater.Updater, k, v int32, r map[int32]int32, n int32) {
	n++
	if n > 100 {
		logger.Alert("IType itemsRandom endless loop:%v", k)
	}
	switch yyds.Config.ITypes.GetIType(k) {
	case config.ITypeItemPacks:
		ItemsPacks.doRandom(u, k, v, r, n)
	case config.ITypeItemGroup:
		ItemsGroup.doRandom(u, k, v, r, n)
	default:
		r[k] += v
	}
}

// ParseItemPacks 独立概率
func itemsPacksRandom(_ *updater.Updater, k, v int32) map[int32]int32 {
	r := map[int32]int32{}
	s := config.GetItemRandom()
	w := s.Packs[k]
	if w == nil {
		return r
	}
	for ; v > 0; v-- {
		for _, id := range w.Probability() {
			if id <= 0 {
				continue
			}
			c := config.Data.ItemPacks[id]
			if c != nil && c.Key > 0 && c.Num > 0 {
				r[c.Key] += c.Num
			}
		}
	}

	return r
}

// 权重
func itemsGroupRandom(_ *updater.Updater, k, v int32) map[int32]int32 {
	r := map[int32]int32{}
	s := config.GetItemRandom()
	w := s.Group[k]
	if w == nil {
		return r
	}
	for ; v > 0; v-- {
		if x := w.Roll(); x >= 0 {
			if c := config.Data.ItemGroup[x]; c != nil {
				r[c.GetKey()] = c.GetNum()
			}
		}
	}
	return r
}
